using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
/// <summary>
/// AssetBundle资源管理器
/// </summary>
public partial class HFABMgr : AbsHFSingleMonoBehaviour<HFABMgr>
{
    /// <summary>
    /// AssetBundleManifest文件
    /// </summary>
    AssetBundleManifest mAssetBundleManifest = null;

    /// <summary>
    /// 资源Key与ManifestName映射
    /// Key:assetBundleKey
    /// Value:带HashCode的资源包名
    /// </summary>
    Dictionary<int, string> mAssetBundleKeyForManifestNameMaping = new Dictionary<int, string>();

    Func<byte[]> m_GetMainifest;
    /// <summary>
    /// 读取外部的bundle包
    /// </summary>
    /// <param name="getmainifest"></param>
    public void RegisterDownloadMainifestFun(Func<byte[]> getmainifest)
    {
        m_GetMainifest = getmainifest;
    }
    /// <summary>
    /// 重新加载AssetBundleManifest
    /// </summary>
    public void ReloadAssetBundleManifest()
    {
        mAssetBundleManifest = null;
        OnReadAssetBundleManifest(null);
    }

    /// <summary>
    /// 读取AssetBundleManifest文件
    /// </summary>
    void OnReadAssetBundleManifest(Action callback)
    {
        if (loadModel != enHFAbLoadModel.Editor)
        {
            if (mAssetBundleManifest == null)
            {
                bool isUseStreamingAssets = false;
                string path = HFAssetBundleHelper.GetAssetBundleManifestFullPath(loadModel, out isUseStreamingAssets).HFTransPathSeparatorCharToUnityChar();
                if (!string.IsNullOrEmpty(path))
                {
                    byte[] mainifest = null;
                    if (loadModel == enHFAbLoadModel.CDNAssets)
                    {
                        stDownLoadFileInfo info = new stDownLoadFileInfo();
                        info.HashCode = path.GetHashCode();
                        info.FileName = SFGlobalSetting.platform;
                        info.UrlPathRoot = SFGlobalSetting.cdnassetBundleRoot;
                        info.Weight = EnGroupWeight.High;
                        HFAssetsDownLoadManager.Instance.AddTask(info, (asset) => {
                            if (asset.Success)
                            {
                                mainifest = asset.data;
                                OnLoadManifest(mainifest);
                                if (mAssetBundleManifest != null)
                                {
                                    OnReadAssetBundleMainifest();
                                }
                            }
                            callback?.Invoke();
                        },null);
                    }
                    else
                    {
                        mainifest = HFAssetBundleHelper.ReadBuffer(path, isUseStreamingAssets);
                        if (mainifest == null)
                        {
                            mainifest = m_GetMainifest?.Invoke();
                        }

                        OnLoadManifest(mainifest);
                        if (mAssetBundleManifest != null)
                        {
                            OnReadAssetBundleMainifest();
                        }
                        callback?.Invoke();
                    }
                }
                else
                {
                    HFP.HFError($"Can't find file AssetBundleManifest【LoadModel：{loadModel}】=>{path}");
                }
            }
            else
            {
                callback?.Invoke();
            }
        }
        else
        {
            callback?.Invoke();
        }        
    }

    private bool OnLoadManifest(byte[] mainifest)
    {
        bool success = false;
        if (mainifest != null)
        {
            AssetBundle ab = AssetBundle.LoadFromMemory(mainifest);
            if (ab != null)
            {
                mAssetBundleManifest = ab.LoadAsset<AssetBundleManifest>(SFGlobalSetting.manifestName);
                success = true;
                ab.Unload(false);
                ab = null;
            }
        }
        return success;
    }

    private void OnReadAssetBundleMainifest()
    {
        string[] names = mAssetBundleManifest.GetAllAssetBundles();
        if (names != null)
        {
            string temp = string.Empty;
            int key = 0;
            for (int i = 0; i < names.Length; i++)
            {
                temp = names[i];
                temp = temp.HFRemoveAssetBundleManifestNameHash();
                key = temp.HFAssetBundleKey();
                mAssetBundleKeyForManifestNameMaping[key]= names[i];
            }
        }
    }

    /// <summary>
    /// 检测资源路径属性语言项
    /// </summary>
    /// <param name="_abPathAttr">资源路径属性</param>
    void OnCheckAssetBundlePathAttributeLanguage(HFAssetBundlePathAttribute _abPathAttr)
    {
        _abPathAttr.ChangeLanguage(HFLanguageHelper.language);
        bool isSameLan = HFLanguageHelper.language == HFLanguageHelper.defaultAlternateLanguage;
        switch (loadModel)
        {//如果当前语言包没有资源，则切换到缺省语言包
            case enHFAbLoadModel.Editor:
                if (!File.Exists(_abPathAttr.editorPath) && !isSameLan)
                {
                    _abPathAttr.ChangeLanguage(HFLanguageHelper.defaultAlternateLanguage);
                }
                break;
            default:
                if (!mAssetBundleKeyForManifestNameMaping.ContainsKey(_abPathAttr.assetBundleKey) && !isSameLan)
                {
                    _abPathAttr.ChangeLanguage(HFLanguageHelper.defaultAlternateLanguage);
                }
                break;
        }
    }

    /// <summary>
    /// 获得资源文件路径
    /// </summary>
    /// <param name="_abPathAttr">资源属性</param>
    /// <param name="_isUseStreamingAssets">是否使用StreamingAssets资源</param>
    /// <param name="_isManifestInclude">是否包含在ManifestInclude文件中</param>
    /// <returns>资源文件路径</returns>
    public string GetAssetBundleFullPath(HFAssetBundlePathAttribute _abPathAttr, out bool _isUseStreamingAssets,out bool _isManifestInclude)
    {
        string result = string.Empty;
        _isUseStreamingAssets = false;
        _isManifestInclude = false;
        if (mAssetBundleKeyForManifestNameMaping.TryGetValue(_abPathAttr.assetBundleKey, out result))
        {//如果当前语言版本有资源
            _isManifestInclude = true;
            result = HFAssetBundleHelper.GetAssetBundleFullPath(result, loadModel, out _isUseStreamingAssets).HFTransPathSeparatorCharToUnityChar();          
        }
        return result;
    }
    /// <summary>
    /// 获取当前BundleAsset中的路径
    /// </summary>
    /// <param name="assetBundleKey">资源Id</param>
    /// <returns></returns>
    public string GetAssetBundleAssetPathByMainifest(int assetBundleKey)
    {
        string result = string.Empty;
        if (mAssetBundleKeyForManifestNameMaping.TryGetValue(assetBundleKey, out result))
        {
        }
        return result;
    }
    /// <summary>
    /// 获得资源文件路径
    /// </summary>
    /// <param name="_abPathAttr">资源属性</param>
    /// <returns>资源文件路径</returns>
    public string[] GetAllDependencies(HFAssetBundlePathAttribute _abPathAttr)
    {
        string[] result = null;
        string abName = string.Empty;
        if (mAssetBundleManifest != null)
        {
            if (mAssetBundleKeyForManifestNameMaping.TryGetValue(_abPathAttr.assetBundleKey, out abName))
            {
                result = mAssetBundleManifest.GetAllDependencies(abName);
            }
        }
        return result;
    }
}
